import 'dart:io';
import '../models/mood_record.dart';
import '../models/media_attachment.dart';
import '../models/mood_type.dart';
import '../models/mood_statistics.dart';
import 'database_helper.dart';

/// 情绪记录数据仓库
/// 提供高级的数据访问接口，封装数据库操作逻辑
class MoodRepository {
  final DatabaseHelper _databaseHelper = DatabaseHelper();

  /// 保存情绪记录
  /// [record] 要保存的情绪记录
  /// 返回保存后的完整记录（包含生成的ID）
  Future<MoodRecord> saveMoodRecord(MoodRecord record) async {
    try {
      // 插入主记录
      final recordId = await _databaseHelper.insertMoodRecord(record);
      
      // 保存媒体附件
      final savedAttachments = <MediaAttachment>[];
      for (final attachment in record.mediaAttachments) {
        final attachmentWithRecordId = attachment.copyWith(
          moodRecordId: recordId,
        );
        final attachmentId = await _databaseHelper.insertMediaAttachment(attachmentWithRecordId);
        savedAttachments.add(attachmentWithRecordId.copyWith(id: attachmentId));
      }
      
      // 返回完整的保存后记录
      return record.copyWith(
        id: recordId,
        mediaAttachments: savedAttachments,
      );
    } catch (e) {
      throw Exception('保存情绪记录失败: $e');
    }
  }

  /// 更新情绪记录
  /// [record] 要更新的情绪记录
  /// 返回更新后的记录
  Future<MoodRecord> updateMoodRecord(MoodRecord record) async {
    try {
      if (record.id == null) {
        throw Exception('无法更新没有ID的记录');
      }
      
      // 更新主记录
      final updatedRecord = record.copyWith(
        updatedAt: DateTime.now(),
      );
      
      await _databaseHelper.updateMoodRecord(updatedRecord);
      
      // 注意：这里简化处理，实际应用中可能需要更复杂的媒体附件更新逻辑
      return updatedRecord;
    } catch (e) {
      throw Exception('更新情绪记录失败: $e');
    }
  }

  /// 删除情绪记录
  /// [id] 要删除的记录ID
  /// 同时删除关联的媒体附件文件
  Future<void> deleteMoodRecord(int id) async {
    try {
      // 获取记录以便删除关联的媒体文件
      final record = await _databaseHelper.getMoodRecord(id);
      if (record != null) {
        // 删除媒体文件
        for (final attachment in record.mediaAttachments) {
          await _deleteMediaFile(attachment.filePath);
          if (attachment.thumbnailPath != null) {
            await _deleteMediaFile(attachment.thumbnailPath!);
          }
        }
      }
      
      // 删除数据库记录（媒体附件会因为外键约束自动删除）
      await _databaseHelper.deleteMoodRecord(id);
    } catch (e) {
      throw Exception('删除情绪记录失败: $e');
    }
  }

  /// 获取情绪记录
  /// [id] 记录ID
  /// 返回情绪记录，如果不存在则返回null
  Future<MoodRecord?> getMoodRecord(int id) async {
    try {
      return await _databaseHelper.getMoodRecord(id);
    } catch (e) {
      throw Exception('获取情绪记录失败: $e');
    }
  }

  /// 获取所有情绪记录
  /// [limit] 限制返回的记录数量
  /// [offset] 偏移量
  /// 返回情绪记录列表
  Future<List<MoodRecord>> getAllMoodRecords({
    int? limit,
    int? offset,
  }) async {
    try {
      return await _databaseHelper.getAllMoodRecords(
        limit: limit,
        offset: offset,
      );
    } catch (e) {
      throw Exception('获取情绪记录列表失败: $e');
    }
  }

  /// 获取今日情绪记录
  /// 返回今天的所有情绪记录
  Future<List<MoodRecord>> getTodayMoodRecords() async {
    try {
      final now = DateTime.now();
      final startOfDay = DateTime(now.year, now.month, now.day);
      final endOfDay = startOfDay.add(const Duration(days: 1));
      
      return await _databaseHelper.getMoodRecordsByDateRange(
        startOfDay,
        endOfDay,
      );
    } catch (e) {
      throw Exception('获取今日情绪记录失败: $e');
    }
  }

  /// 获取本周情绪记录
  /// 返回本周的所有情绪记录
  Future<List<MoodRecord>> getThisWeekMoodRecords() async {
    try {
      final now = DateTime.now();
      final startOfWeek = now.subtract(Duration(days: now.weekday - 1));
      final startOfWeekDay = DateTime(startOfWeek.year, startOfWeek.month, startOfWeek.day);
      final endOfWeek = startOfWeekDay.add(const Duration(days: 7));
      
      return await _databaseHelper.getMoodRecordsByDateRange(
        startOfWeekDay,
        endOfWeek,
      );
    } catch (e) {
      throw Exception('获取本周情绪记录失败: $e');
    }
  }

  /// 获取本月情绪记录
  /// 返回本月的所有情绪记录
  Future<List<MoodRecord>> getThisMonthMoodRecords() async {
    try {
      final now = DateTime.now();
      final startOfMonth = DateTime(now.year, now.month, 1);
      final endOfMonth = DateTime(now.year, now.month + 1, 1);
      
      return await _databaseHelper.getMoodRecordsByDateRange(
        startOfMonth,
        endOfMonth,
      );
    } catch (e) {
      throw Exception('获取本月情绪记录失败: $e');
    }
  }

  /// 根据日期范围获取情绪记录
  /// [startDate] 开始日期
  /// [endDate] 结束日期
  /// 返回指定日期范围内的情绪记录列表
  Future<List<MoodRecord>> getMoodRecordsByDateRange(
    DateTime startDate,
    DateTime endDate,
  ) async {
    try {
      return await _databaseHelper.getMoodRecordsByDateRange(
        startDate,
        endDate,
      );
    } catch (e) {
      throw Exception('获取日期范围内的情绪记录失败: $e');
    }
  }

  /// 根据情绪类型获取记录
  /// [moodType] 情绪类型
  /// 返回指定情绪类型的记录列表
  Future<List<MoodRecord>> getMoodRecordsByType(MoodType moodType) async {
    try {
      return await _databaseHelper.getMoodRecordsByType(moodType);
    } catch (e) {
      throw Exception('获取指定情绪类型的记录失败: $e');
    }
  }

  /// 搜索情绪记录
  /// [keyword] 搜索关键词
  /// 返回包含关键词的记录列表
  Future<List<MoodRecord>> searchMoodRecords(String keyword) async {
    try {
      if (keyword.trim().isEmpty) {
        return [];
      }
      return await _databaseHelper.searchMoodRecords(keyword.trim());
    } catch (e) {
      throw Exception('搜索情绪记录失败: $e');
    }
  }

  /// 获取情绪统计数据
  /// [startDate] 统计开始日期
  /// [endDate] 统计结束日期
  /// 返回指定时间范围内的情绪统计信息
  Future<MoodStatistics> getMoodStatistics(
    DateTime startDate,
    DateTime endDate,
  ) async {
    try {
      final records = await getMoodRecordsByDateRange(startDate, endDate);
      return MoodStatistics.fromRecords(records, startDate, endDate);
    } catch (e) {
      throw Exception('获取情绪统计数据失败: $e');
    }
  }

  /// 获取最近7天的情绪统计
  /// 返回最近一周的情绪统计信息
  Future<MoodStatistics> getRecentWeekStatistics() async {
    try {
      final endDate = DateTime.now();
      final startDate = endDate.subtract(const Duration(days: 7));
      return await getMoodStatistics(startDate, endDate);
    } catch (e) {
      throw Exception('获取最近一周统计数据失败: $e');
    }
  }

  /// 获取最近30天的情绪统计
  /// 返回最近一个月的情绪统计信息
  Future<MoodStatistics> getRecentMonthStatistics() async {
    try {
      final endDate = DateTime.now();
      final startDate = endDate.subtract(const Duration(days: 30));
      return await getMoodStatistics(startDate, endDate);
    } catch (e) {
      throw Exception('获取最近一个月统计数据失败: $e');
    }
  }

  /// 获取数据库统计信息
  /// 返回包含记录总数、最早记录日期等信息的Map
  Future<Map<String, dynamic>> getDatabaseStats() async {
    try {
      return await _databaseHelper.getDatabaseStats();
    } catch (e) {
      throw Exception('获取数据库统计信息失败: $e');
    }
  }

  /// 检查今天是否已有记录
  /// 返回true表示今天已有记录，false表示今天还没有记录
  Future<bool> hasTodayRecord() async {
    try {
      final todayRecords = await getTodayMoodRecords();
      return todayRecords.isNotEmpty;
    } catch (e) {
      throw Exception('检查今日记录失败: $e');
    }
  }

  /// 获取最新的情绪记录
  /// [count] 要获取的记录数量，默认为1
  /// 返回最新的情绪记录列表
  Future<List<MoodRecord>> getLatestMoodRecords({int count = 1}) async {
    try {
      return await _databaseHelper.getAllMoodRecords(
        limit: count,
        orderBy: 'created_at DESC',
      );
    } catch (e) {
      throw Exception('获取最新情绪记录失败: $e');
    }
  }

  /// 获取情绪记录总数
  /// 返回数据库中的情绪记录总数
  Future<int> getTotalRecordsCount() async {
    try {
      final stats = await getDatabaseStats();
      return stats['totalRecords'] as int;
    } catch (e) {
      throw Exception('获取记录总数失败: $e');
    }
  }

  /// 删除媒体文件
  /// [filePath] 文件路径
  /// 安全地删除媒体文件，如果文件不存在则忽略
  Future<void> _deleteMediaFile(String filePath) async {
    try {
      final file = File(filePath);
      if (await file.exists()) {
        await file.delete();
      }
    } catch (e) {
      // 忽略文件删除错误，避免影响数据库操作
      print('删除媒体文件失败: $filePath, 错误: $e');
    }
  }

  /// 清除所有记录
  /// 删除所有情绪记录和相关的媒体文件
  Future<void> clearAllRecords() async {
    try {
      // 获取所有记录以便删除媒体文件
      final allRecords = await getAllMoodRecords();
      
      // 删除所有媒体文件
      for (final record in allRecords) {
        for (final attachment in record.mediaAttachments) {
          await _deleteMediaFile(attachment.filePath);
          if (attachment.thumbnailPath != null) {
            await _deleteMediaFile(attachment.thumbnailPath!);
          }
        }
      }
      
      // 删除数据库中的所有记录
      await _databaseHelper.clearAllRecords();
    } catch (e) {
      throw Exception('清除所有记录失败: $e');
    }
  }

  /// 根据ID获取情绪记录
  /// [recordId] 记录ID字符串
  /// 返回对应的情绪记录，如果不存在则返回null
  Future<MoodRecord?> getRecordById(String recordId) async {
    try {
      final id = int.tryParse(recordId);
      if (id == null) {
        return null;
      }
      return await getMoodRecord(id);
    } catch (e) {
      throw Exception('根据ID获取记录失败: $e');
    }
  }

  /// 清理数据库（用于测试或重置）
  /// 删除所有数据并重新初始化数据库
  Future<void> clearDatabase() async {
    try {
      await _databaseHelper.deleteDatabase();
    } catch (e) {
      throw Exception('清理数据库失败: $e');
    }
  }

  /// 关闭数据库连接
  Future<void> close() async {
    await _databaseHelper.close();
  }
}